import './interface/options';

class DialogDom {
    dialog: HTMLElement;
    cover?: HTMLElement;
    opt: Options;
    left: number = 0;
    top: number = 0;
    maxLeft: number = 0;
    maxTop: number = 0;
    mt: string | null = null;

    constructor(opt: Options) {
        this.opt = opt;
        const dom = DialogDom.show(opt);
        this.dialog = this.createDialog(opt);
        dom.appendChild(this.dialog)
        document.body.appendChild(dom);
        this.resetPosition();
        // let a: NodeJS.Timeout;
        // window.addEventListener('resize', () => {
        //     clearTimeout(a);
        //     a = setTimeout(() => {
        //         this.resetPosition();
        //     }, 200)
        // })
    }

    // 计算位置和宽高
    private resetPosition() {
        // if (this.opt.width.indexOf('%') == -1) {
        //     if (this.dialog.offsetWidth > window.innerWidth) {
        //         this.dialog.style.width = window.innerWidth + 'px';
        //     }
        //
        // }
        // if (this.opt.height.indexOf('%') == -1) {
        //     if (this.dialog.offsetHeight > window.innerHeight) {
        //         this.dialog.style.height = window.innerHeight + 'px';
        //     }
        // }
        this.dialog.style.top = (window.innerHeight - this.dialog.offsetHeight) / 2 + 'px';
        this.dialog.style.left = (window.innerWidth - this.dialog.offsetWidth) / 2 + 'px';
    }

    /**
     * 遮罩层
     * @param opt
     * @private
     */
    private static show(opt: Options): HTMLElement {
        const dom: HTMLElement = document.createElement('div');
        dom.className = 'hades-dialog';
        dom.style.zIndex = opt.zIndex + '';
        return dom;
    }

    /**
     * 主体
     * @param opt
     * @private
     */
    private createDialog(opt: Options): HTMLElement {
        const div: HTMLElement = document.createElement('div');
        div.className = 'hades-dialog-main';
        div.style.height = opt.height;
        div.style.width = opt.width;
        div.appendChild(this.createTitle(opt))
        div.appendChild(this.createContent(opt.src))
        this.createResizeBar(div)
        return div;
    }

    private createResizeBar(parent: HTMLElement) {
        const tb: HTMLElement = document.createElement('div'),
            rb: HTMLElement = document.createElement('div'),
            bb: HTMLElement = document.createElement('div'),
            lb: HTMLElement = document.createElement('div');
        tb.className = 'hades-dialog-top-bar';
        rb.className = 'hades-dialog-right-bar';
        bb.className = 'hades-dialog-bottom-bar';
        lb.className = 'hades-dialog-left-bar';
        tb.setAttribute('t', 't');
        rb.setAttribute('t', 'r');
        bb.setAttribute('t', 'b');
        lb.setAttribute('t', 'l');
        this.resizeMouseDown(tb);
        this.resizeMouseDown(rb);
        this.resizeMouseDown(bb);
        this.resizeMouseDown(lb);
        parent.appendChild(tb);
        parent.appendChild(rb);
        parent.appendChild(bb);
        parent.appendChild(lb);
    }

    // 调整大小
    resizeMouseDown(dom: HTMLElement) {
        if (this.opt.max) {
            return;
        }

        const _this = this;

        function resizeMouseMove(e: MouseEvent) {
            _this.resizeMouseMove(e)
        }

        function resizeMouseUp() {
            if (_this.cover) {
                _this.cover.style.display = 'none';
            }
            document.removeEventListener('mousemove', resizeMouseMove, false);
            document.removeEventListener('mouseup', resizeMouseUp, false);
        }

        dom.addEventListener('mousedown', (e: MouseEvent) => {
            this.left = e.clientX;
            this.top = e.clientY;
            let dom = e.target as HTMLElement;
            this.mt = dom.getAttribute('t');
            if (_this.cover) {
                _this.cover.style.display = 'block';
            }
            if (this.opt.max) {
                return;
            }
            // 绑定事件
            document.addEventListener('mousemove', resizeMouseMove, false)
            document.addEventListener('mouseup', resizeMouseUp, false);
        });

    }

    resizeMouseMove(e: MouseEvent) {
        let num = 0;
        switch (this.mt) {
            case "r":
                num = this.dialog.offsetWidth + e.clientX - this.left;
                if (num > 300) {
                    this.left = e.clientX;
                    this.dialog.style.width = num + 'px';
                }
                break;
            case "l":
                num = this.left - e.clientX;
                if (this.dialog.offsetWidth + num > 300) {
                    this.left = e.clientX;
                    this.dialog.style.left = (this.dialog.offsetLeft - num) + 'px';
                    this.dialog.style.width = (this.dialog.offsetWidth + num) + 'px';
                }
                break;
            case "t":
                num = this.top - e.clientY;
                if (this.dialog.offsetHeight + num > 200 && e.clientY > 0) {
                    this.top = e.clientY;
                    this.dialog.style.top = (this.dialog.offsetTop - num) + 'px';
                    this.dialog.style.height = (this.dialog.offsetHeight + num) + 'px';
                }
                break;
            case "b":
                num = this.dialog.offsetHeight + e.clientY - this.top;
                if (num > 200 && e.clientY <= window.innerHeight) {
                    this.top = e.clientY;
                    this.dialog.style.height = num + 'px';
                }
                break;
        }
    }

    /**
     * 标题
     * @param opt
     * @private
     */
    private createTitle(opt: Options): HTMLElement {
        const title: HTMLElement = document.createElement('div'),
            act: HTMLElement = document.createElement('div'),
            span: HTMLElement = document.createElement('span');
        span.className = "hades-dialog-title-text";
        span.innerText = opt.title;
        title.className = "hades-dialog-title";
        title.style.backgroundColor = '#1890ff';
        act.className = 'hades-dialog-act';
        act.appendChild(this.createHelpBtn());
        act.appendChild(this.createSizeBtn());
        act.appendChild(this.createCloseBtn());
        title.appendChild(act);
        title.appendChild(span);
        this.titleEvent(title);
        return title;
    }

    /**
     * 标题鼠标移动事件
     * @param e
     * @private
     */
    private mouseMoveEvent(e: MouseEvent) {
        let left = e.clientX - this.left,
            top = e.clientY - this.top;
        if (left < 0) {
            left = 0;
        } else if (this.maxLeft < left) {
            left = this.maxLeft
        }
        if (top < 0) {
            top = 0;
        } else if (this.maxTop < top) {
            top = this.maxTop
        }
        this.dialog.style.left = left + 'px';
        this.dialog.style.top = top + 'px';
    }

    private titleEvent(title: HTMLElement) {
        const _this = this;

        function mouseMoveEvent(e: MouseEvent) {
            _this.mouseMoveEvent(e);
        }

        function documentOutEvent() {
            if (_this.cover) {
                _this.cover.style.display = 'none';
            }
            document.removeEventListener('mousemove', mouseMoveEvent, false)
            document.removeEventListener('mouseup', documentOutEvent, false)
        }

        title.addEventListener('mousedown', (e) => {
            if (this.opt.max) {
                return;
            }
            this.left = e.offsetX;
            this.top = e.offsetY;
            this.maxLeft = window.innerWidth - this.dialog.offsetWidth;
            this.maxTop = window.innerHeight - this.dialog.offsetHeight;
            if (this.cover) {
                this.cover.style.display = 'block';
            }
            document.addEventListener('mousemove', mouseMoveEvent, false);
            document.addEventListener('mouseup', documentOutEvent, false);
        })
    }

    /**
     * 关闭按钮
     * @private
     */
    private createCloseBtn(): HTMLElement {
        const btn = DialogDom.createIco('close', '关闭');
        btn.addEventListener('mousedown', (e) => {
            this.close({type: '_ico'});
            e.stopPropagation();
        })
        return btn;
    }

    /**
     * 帮助按钮
     * @private
     */
    private createHelpBtn(): HTMLElement {
        const btn = DialogDom.createIco('help', '帮助');
        btn.addEventListener('mousedown', (e) => {
            e.stopPropagation();
            this.opt.helpHandler();
        })
        return btn;
    }

    /**
     * 最大化/最小化按钮
     * @private
     */
    private createSizeBtn(): HTMLElement {
        let btn: HTMLElement;
        if (this.opt.max) {
            btn = DialogDom.createIco('size', '最大化');
        } else {
            btn = DialogDom.createIco('size', '恢复');
        }
        btn.addEventListener('mousedown', (e) => {
            if (this.opt.max) {
                this.dialog.classList.remove('hades-dialog-max');
                btn.title = '最大化'
                this.opt.max = false;
            } else {
                this.opt.max = true;
                btn.title = '恢复'
                this.dialog.classList.add('hades-dialog-max');
            }
            e.stopPropagation();
        })
        return btn;
    }

    /**
     * 图标
     * @param className
     * @param title
     * @private
     */
    private static createIco(className: string, title: string): HTMLElement {
        const ico: HTMLElement = document.createElement('i');
        ico.className = 'hades-dialog-ico hades-dialog-ico-' + className;
        ico.setAttribute('title', title);
        return ico;
    }

    /**
     * 主体内容
     * @param src
     * @private
     */
    private createContent(src: string): HTMLElement {
        const iframe: HTMLElement = document.createElement('iframe');
        const cover: HTMLElement = document.createElement('div');
        const div: HTMLElement = document.createElement('div');
        iframe.className = 'hades-dialog-iframe';
        iframe.setAttribute('src', src);
        cover.className = 'hades-dialog-iframe-cover';
        div.className = 'hades-dialog-body';
        div.appendChild(iframe);
        div.appendChild(cover);
        this.cover = cover;
        return div;
    }

    /**
     * 关闭窗口
     */
    close(obj: object) {
        this.opt.closeHandler(obj);
        this.dialog.parentNode && document.body.removeChild(this.dialog.parentNode)
    }
}

export default DialogDom;
